import os
import time
from typing import List,Optional
from datetime import datetime,timedelta
from .commons import get_timestamp,zip_files
from .const import PATH_ROBOT_INSTANCE,PATH_ROBOT_ZIP_TEMP


class RobotBizException(Exception):
    pass

class RobotFile(object):

    @staticmethod
    def match_content_in_file(filename: str, content: str, encoding: str = "gbk") -> bool:
        """
        查找文件中是否存在给定内容
        :param filename:
        :param content:
        :param encoding:
        :return:
        """
        with open(filename, mode="r", encoding=encoding) as f:
            for line in f:
                if content in line:
                    return True

    @classmethod
    def delete_zip_file(cls):
        """
        删除历史的ZIP文件
        :return:
        """
        if not os.path.exists(PATH_ROBOT_ZIP_TEMP):
            return
        files = [os.path.join(PATH_ROBOT_ZIP_TEMP,file_name ) for file_name in os.listdir(PATH_ROBOT_ZIP_TEMP)]
        if files:
            timestamp = (datetime.today() - timedelta(hours=1)).timestamp()
            for f in files:
                t = os.path.getctime(f)
                if timestamp > t:
                    os.remove(f)

    @staticmethod
    def get_robot_instances() -> List[str]:
        """
        获取本机机器人实例目录名
        :return: 机器人实例目录列表
        """
        instance_paths = []
        files = os.listdir(os.path.join(PATH_ROBOT_INSTANCE))
        for f in files:
            file_path = os.path.join(PATH_ROBOT_INSTANCE, f)
            if os.path.isdir(file_path):
                instance_paths.append(file_path)

        return instance_paths if len(instance_paths) > 0 else None

    @staticmethod
    def makeup_robot_instance_log_name(inst_dir: str, file_date: str) -> str:
        return os.path.join(inst_dir, "driver", "log", "robotProcessor" + file_date + ".log")

    @classmethod
    def get_log_file(cls,pid: str,file_date: str) -> str:
        """
        获取机器人实例下指定日期的日志文件
        :param pid:
        :param file_date:
        :return: 日志文件压缩包文件路径
        """
        #清理历史文件
        cls.delete_zip_file()
        files = []
        if pid != "*":
            if os.path.exists(os.path.join(PATH_ROBOT_INSTANCE, pid)):
                log_file = cls.makeup_robot_instance_log_name(os.path.join(PATH_ROBOT_INSTANCE, pid), file_date)
                if os.path.exists(log_file):
                    files.append(log_file)
            else:
                raise RobotBizException("机器人实例不存在")
        else:
            paths = cls.get_robot_instances()
            if not paths:
                raise RobotBizException("机器人实例不存在")
            for path in paths:
                log_file = cls.makeup_robot_instance_log_name(path, file_date)
                if os.path.exists(log_file):
                    files.append(log_file)

        if len(files) == 0:
            raise RobotBizException("未找到匹配的日志文件")
        zip_file = zip_files(files)
        return zip_file

    @classmethod
    def get_filter_log_files(cls,content: str, file_date_start: str, file_date_end: str, pid: Optional[str] = None) -> str:
        """
        查找含有给定content的日志文件
        :param content:
        :param file_date_start:
        :param file_date_end:
        :param pid:
        :return:
        """
        # 清理历史文件
        cls.delete_zip_file()
        instance_dirs = []
        log_files = []
        # 获取实例目录
        if pid and pid != "*":
            if os.path.exists(os.path.join(PATH_ROBOT_INSTANCE, pid)):
                instance_dirs.append(os.path.join(PATH_ROBOT_INSTANCE, pid))
        else:
            instance_dirs = cls.get_robot_instances()

        today = datetime.strptime(file_date_end, "%Y-%m-%d").date()
        temp_date = datetime.strptime(file_date_start, "%Y-%m-%d").date()
        while today >= temp_date:
            file_date = temp_date.strftime("%Y%m%d")
            for inst_dir in instance_dirs:
                log_file = cls.makeup_robot_instance_log_name(inst_dir, file_date)
                # print(log_file)
                if os.path.exists(log_file):
                    log_files.append(log_file)
            temp_date = temp_date + timedelta(days=1)
        # 开始查找日志内容
        # print(log_files)
        files = []
        for f in log_files:
            print(f)
            if cls.match_content_in_file(f, content):
                files.append(f)

        if len(files) > 0:
            zip_file = zip_files(files)
            return  zip_file
        else:
            raise RobotBizException("未找到包含此内容的日志文件")

    @staticmethod
    def makeup_robot_instance_task_name(inst_dir: str, task_id: str) -> str:
        return os.path.join(inst_dir, "driver", "temp", task_id, "task.txt")

    @classmethod
    def get_task(cls,pid: str, task_id: str):
        """
        获取指定ID的任务文件
        :param pid: 机器人实例名, *表示所有实例下查找
        :param task_id: 任务ID
        :return:
        """
        # 清理历史文件
        cls.delete_zip_file()
        files = []
        if pid != "*":
            if os.path.exists(os.path.join(PATH_ROBOT_INSTANCE, pid)):
                task_file = cls.makeup_robot_instance_task_name(os.path.join(PATH_ROBOT_INSTANCE, pid), task_id)
                if os.path.exists(task_file):
                    files.append(task_file)
            else:
                raise RobotBizException("机器人实例不存在")
        else:
            paths = cls.get_robot_instances()
            if not paths:
                raise RobotBizException("机器人实例不存在")
            for path in paths:
                task_file = cls.makeup_robot_instance_task_name(path, task_id)
                if os.path.exists(task_file):
                    files.append(task_file)

        if len(files) == 0:
            raise RobotBizException("未找到匹配的任务文件")
        return zip_files(files)